home *** CD-ROM | disk | FTP | other *** search
- #include "stdlib.h"
- #include "stdio.h"
- #include "conio.h"
- #include "string.h"
- #include "graph.fd"
- #include "halo.h"
-
- #define OK 1
- #define FAIL 0
- #define TRUE 1
- #define FALSE 0
-
- #define CMD_DELIMITER " \t\n"
- #define VAL_DELIMITER ",\n"
- #define TICK_WIDTH 0.025
- #define SQRT_2 1.414213562
-
- char *cmd_strs[] = {"DATA","COLORS","MODE","ATTRIBUTES","SCALE","LEGEND",
- "FONT","TITLES","DEVICE","PRINTER","COMMENT","END" };
- enum cmd_vals { C_DATA, C_COLORS, C_MODE, C_ATTRIBUTES, C_SCALE, C_LEGEND,
- C_FONT, C_TITLES, C_DEVICE, C_PRINTER, C_COMMENT, C_END };
-
- #define NUM_CMD_VALS ((int)C_END)
- union udata {
- float fdata[64]; /* Numeric data for commands (e.g. COLORS) */
- char cdata[16][16]; /* String data for commands (e.g. LEGEND) */
- };
-
- typedef struct cmd_data_type {
- union udata d; /* Commands data is string or numeric */
- int count; /* Number of data items found in command */
- } cmd_data_type, *cmd_data_type_p;
-
- typedef struct { /* HALO '88 specific global data */
- char *device; /* Name of HALO screen device driver */
- char *font; /* Name of HALO stroke font file */
- float x1,y1,x2,y2; /* World coordinates rectangle values */
- int degree_mode; /* if true use degrees, else radians */
- int lnstyle; /* Line style, 1 <= lnstyle <= 10 */
- int lnwidth; /* Line thickness in pixels, always odd */
- int maxcolor; /* Number of colors supported by device */
- int mode; /* Device dependent graphics mode */
- } halo_type;
-
- typedef struct {
- float start_x, start_y; /* Bottom corner of graph draw area */
- float end_x, end_y; /* Upper corner of graph draw area */
- float scale_min, scale_max; /* Y-Axis min and max values */
- int num_points; /* Number of points in DATA file */
- int num_ticks; /* Number of ticks on the Y-Axis */
- int num_colors; /* Number of user-supplied colors */
- char *legend; /* User-supplied LEGEND */
- } graph_type;
-
- cmd_data_type cmd_data[NUM_CMD_VALS];
- halo_type halo;
- graph_type graph;
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- char inp_line[128];
- FILE *infile;
-
- if (argc>1) { /* First argv should be input data file */
- if ((infile=fopen(argv[1],"r")) == NULL) {
- fprintf(stderr,"Error: can't open %s\n",argv[1]);
- exit(-1);
- }
- }
- else { /* no data file was given */
- fprintf(stderr,"Usage: graph inputfile\n");
- exit(-1);
- }
-
- memset(cmd_data, 0, sizeof(cmd_data));
-
- while(fgets(inp_line,sizeof(inp_line)-1,infile) != NULL)
- process_graphics_cmd_line(inp_line);
- fclose(infile);
-
- setup_halo_globals(); /* Capture relevant parameters */
- setup_graph_globals();
- draw_bar_graph(); /* Draw the actual graph */
- deltcur(); /* Remove text "_" cursor */
- getch();
- print_graph(); /* Print graph if requested */
- closegraphics(); /* Close out all devices */
- return OK;
- }
-
-
-
- int process_graphics_cmd_line(inp_line)
- char *inp_line;
- {
- char input[128];
- char *cmd_keywd;
- int found = FALSE;
- int cmd_val;
-
- strcpy(input,inp_line);
- if ((cmd_keywd=strtok(input,CMD_DELIMITER)) == NULL) {
- fprintf(stderr,"Unable to parse to command <%s>\n",inp_line);
- return FAIL;
- }
-
- for (cmd_val=0; cmd_val<=NUM_CMD_VALS; cmd_val++)
- if (stricmp(cmd_strs[cmd_val],cmd_keywd)==0) {
- found = TRUE;
- break;
- }
-
- if (!found) {
- fprintf(stderr,"Keyword <%s> not recognized.\n",cmd_keywd);
- return FAIL;
- }
-
- if (cmd_val <= C_SCALE)
- parse_delimited_number_list(&cmd_data[cmd_val]);
- else
- parse_delimited_string_list(&cmd_data[cmd_val]);
- return OK;
- }
-
-
-
- void parse_delimited_number_list(data_p)
- cmd_data_type *data_p;
- {
- int i;
- char *cmd_data;
-
- i = data_p->count;
- while ((cmd_data=strtok(NULL,VAL_DELIMITER)) != NULL)
- data_p->d.fdata[i++] = (float) atof(cmd_data);
- data_p->count = i;
- }
-
-
-
- void parse_delimited_string_list(data_p)
- cmd_data_type_p data_p;
- {
- int i;
- char *cmd_data;
-
- i = data_p->count;
- while ((cmd_data=strtok(NULL,VAL_DELIMITER)) != NULL)
- strcpy(data_p->d.cdata[i++],cmd_data);
- data_p->count = i;
- }
-
-
-
- void setup_halo_globals()
- {
- if (cmd_data[C_DEVICE].count) /* Was there a DEVICE command? */
- halo.device = cmd_data[C_DEVICE].d.cdata[0];
- else /* No, use the default */
- halo.device = "HALOIBMG.DEV";
- printf("using device <%s>, press any key to start:\n",halo.device);
- getch();
- setdev(halo.device); /* Initialize the graphics device */
-
- halo.mode = (int) cmd_data[C_MODE].d.fdata[0];
- initgraphics(&halo.mode); /* Clear screen in given mode */
- halo.degree_mode = 1;
- setdegree(&halo.degree_mode); /* Use degrees, not radians */
- halo.x1 = (float) 0.0; halo.y1 = (float) 0.0;
- halo.x2 = (float) 1.0; halo.y2 = (float) 1.0;
- setworld(&halo.x1,&halo.y1,&halo.x2,&halo.y2); /* World rectangle */
- inqcrange(&halo.maxcolor ); /* Find max color value */
- halo.lnwidth = 1;
- setlnwidth(&halo.lnwidth) ; /* Line width is 1 pixel */
- halo.lnstyle = 1;
- setlnstyle(&halo.lnstyle); /* Line style is solid */
- setcolor(&halo.maxcolor); /* Max screen color is usually white */
-
- if (cmd_data[C_FONT].count) /* Was there a FONT command? */
- halo.font = cmd_data[C_FONT].d.cdata[0];
- else /* No, use the default */
- halo.font = "HALO104.FNT";
- setfont(halo.font); /* Load font from disk file */
- setstclr(&halo.maxcolor,&halo.maxcolor) ; /* Set stroke text color */
- }
-
-
- void setup_graph_globals()
- {
- float *data_ptr;
- int i;
-
- /* This rectangle is the active drawing area of the global window */
- graph.start_x = (float) 0.1; graph.end_x = (float) 0.9;
- graph.start_y = (float) 0.15; graph.end_y = (float) 0.88;
- graph.num_ticks = 10;
- graph.num_points = cmd_data[C_DATA].count;
- graph.num_colors = cmd_data[C_COLORS].count;
- graph.legend = cmd_data[C_LEGEND].d.cdata[0];
-
- if (cmd_data[C_SCALE].count) { /* User supplied SCALE boundaries */
- graph.scale_min = cmd_data[C_SCALE].d.fdata[0];
- graph.scale_max = cmd_data[C_SCALE].d.fdata[1];
- }
- else { /* No SCALE bounds, use min and max data values for SCALE */
- graph.scale_min = (float) 0.0;
- graph.scale_max = (float) 0.0;
- data_ptr = cmd_data[C_DATA].d.fdata;
- for (i=0; i < graph.num_points; i++, data_ptr++) {
- if (graph.scale_min > *data_ptr)
- graph.scale_min = *data_ptr; /* New minimum data point */
- if (graph.scale_max < *data_ptr)
- graph.scale_max = *data_ptr; /* New maximum data point */
- }
- }
- }
-
-
- void draw_axes(bar_width)
- double bar_width;
- {
- int i;
- float tick_interval; /* Distance between Y-Axis ticks */
- float axis_interval; /* Y-Axis tick value in scale units */
- float height = (float) 0.10; /* Stroke text height */
- float angle = (float) 45.0; /* Stroke text drawing angle */
- float asp = (float) 1.0; /* Stroke text aspect ratio */
- int path = 0; /* Stroke text path */
- float text_height; /* Inquired height of text string */
- float text_width; /* Inquired width of text String */
- float offse; /* Offset for descenders */
- float x_val, y_val; /* General-purpose registers */
- char axis_label[20]; /* String used to label a tick */
- char *title; /* User-specified graph TITLE */
-
- /* draw the legend above the graph */
- setstext(&height,&asp,&path);
- inqstsize(graph.legend,&text_height,&text_width,&offse);
- x_val = (halo.x2-text_width)/2.0;
- y_val = (float) 0.99 - height;
- movtcurabs(&x_val,&y_val);
- stext(graph.legend);
-
- /* draw X and Y axes */
- draw_line(graph.start_x, graph.start_y, graph.end_x, graph.start_y);
- draw_line(graph.start_x, graph.start_y, graph.start_x, graph.end_y);
- tick_interval = (graph.end_y - graph.start_y) / graph.num_ticks;
- axis_interval = (graph.scale_max - graph.scale_min) / graph.num_ticks;
- height = tick_interval * 0.80; /* text height is 80% of tick dist. */
- setstext(&height,&asp,&path);
-
- /* Draw ticks and label the Y-Axis */
- y_val = graph.start_y;
- for (i=0; i<graph.num_ticks+1; i++) {
- sprintf(axis_label,"%d", (int)(graph.scale_min + axis_interval * i));
- inqstsize(axis_label,&text_height,&text_width,&offse);
- x_val = graph.start_x - 1.5 * TICK_WIDTH - text_width;
- movtcurabs(&x_val,&y_val);
- stext(axis_label);
- draw_line(graph.start_x-TICK_WIDTH,y_val,graph.start_x+TICK_WIDTH,y_val);
- y_val += tick_interval;
- }
-
- /* draw bar labels at a 45-degree angle along the X-Axis */
- setstang(&angle);
- for (i=0; i<graph.num_points; i++) {
- title = cmd_data[C_TITLES].d.cdata[i];
- inqstsize(title,&text_height,&text_width,&offse);
- x_val = graph.start_x + (i+0.5) * bar_width - text_width/SQRT_2;
- y_val = graph.start_y - (text_height*1.25 + text_width/SQRT_2);
- movtcurabs(&x_val,&y_val);
- stext(title); /* draw the actual text */
- }
- }
-
-
- void draw_bar_graph()
- {
- float bar_width; /* Width of a bar in display units */
- float bar_height; /* Height of a bar in display units */
- int bar_color; /* Color to draw the bar with */
- float *data_ptr; /* Used to fetch user's DATA */
- int i;
- int hatch_style; /* Hatch style to draw the bar with */
-
- /* draw_legend(); */
-
- data_ptr = cmd_data[C_DATA].d.fdata; /* 1st data point to plot */
- bar_width = (graph.end_x - graph.start_x) / graph.num_points;
- draw_axes(bar_width);
- for (i=0; i<graph.num_points; i++, data_ptr++) {
- if (graph.num_colors && halo.maxcolor>1) {
- bar_color = (int) cmd_data[C_COLORS].d.fdata[i % graph.num_colors];
- setcolor(&bar_color);
- }
- else { /* Monochrome display or color display with no COLORS data */
- hatch_style = (i % 4) + 1;
- sethatchstyle(&hatch_style);
- }
- bar_height = (*data_ptr - graph.scale_min) /
- (graph.scale_max - graph.scale_min) * (graph.end_y - graph.start_y);
- draw_bar(graph.start_x+i*bar_width, graph.start_y,
- graph.start_x+(i+1)*bar_width, graph.start_y + bar_height);
- }
-
- }
-
-
- void print_graph()
- {
- char *print_name;
- int print_attr[18];
- int i;
-
- print_name = cmd_data[C_PRINTER].d.cdata[0];
- if (*print_name == '\0')
- return; /* If no printer specified, do not print */
- setprn(print_name);
- if (cmd_data[C_ATTRIBUTES].count) { /* Device-specific attribs */
- for (i=0; i < cmd_data[C_ATTRIBUTES].count; i++)
- print_attr[i] = cmd_data[C_ATTRIBUTES].d.fdata[i];
- setpattr(print_attr);
- }
- gprint();
- }
-
-
- void draw_bar(x1,y1,x2,y2) /* Draw a bar from (x1,y1) to (x2,y2) */
- double x1,y1,x2,y2;
- {
- float x1_t,y1_t,x2_t,y2_t;
-
- x1_t = (float)x1; y1_t = (float)y1; x2_t = (float)x2; y2_t = (float)y2;
- bar(&x1_t,&y1_t,&x2_t,&y2_t);
- }
-
-
- void draw_line(x1,y1,x2,y2) /* Draw a line from (x1,y1) to (x2,y2) */
- double x1,y1,x2,y2;
- {
- float x1_t,y1_t,x2_t,y2_t;
-
- x1_t = (float)x1; y1_t = (float)y1; x2_t = (float)x2; y2_t = (float)y2;
- movabs(&x1_t,&y1_t);
- lnabs(&x2_t,&y2_t);
- }